include('shared.lua')

language.Add("mining_laser", "Mining Laser")

//Effect Materials
local BeamMat = Material("effects/mining_beam/mining_laser")
BeamMat:SetMaterialInt("$spriterendermode",0)
BeamMat:SetMaterialInt("$illumfactor",8)
BeamMat:SetMaterialFloat("$alpha",0.9)
BeamMat:SetMaterialInt("$nocull",1)
local FlareMat = Material("sprites/light_glow01")
FlareMat:SetMaterialInt("$spriterendermode",0)
FlareMat:SetMaterialInt("$illumfactor",8)
FlareMat:SetMaterialFloat("$alpha",0.7)
FlareMat:SetMaterialInt("$nocull",1)

//Vars

//Sprite visibility checking
local function checkCanSee(vec1, vec2, filter)
	local tracedata = {}
	tracedata.start = vec1
	tracedata.endpos = vec2
	if ValidEntity(LocalPlayer()) then //Why the FUCK does LocalPlayer() return NIL sometimes?
		tracedata.filter = filter
	end
	tracedata.mask = CONTENTS_SOLID + CONTENTS_MOVEABLE + CONTENTS_OPAQUE + CONTENTS_DEBRIS + CONTENTS_HITBOX + CONTENTS_MONSTER
	
	local traceline = util.TraceLine(tracedata)
	if !traceline.Hit then
		return true
	end
	
	return false
end

//Clientside Processing
function ENT:Draw()

	self:DrawModel()

	//Effect Spawning
	if self.Entity:GetNetworkedBool("On") then
		
		self.LaserType = self.Entity:GetNWFloat("LType")
		
		//Determines Vars based on Laser Type
		if self.LaserType == 1 then
			self.BeamLength = 600
			self.BeamColor = Color(255,255,128,255)
			self.BeamWidth = 25
			self.BeamPulse = 5
			self.SpriteSize = 100
			self.SpritePulse = 25
			self.SPoint = 25
			self.RenderBounds = -150
			
			self.FDir = self.Entity:GetUp()
		
		elseif self.LaserType == 2 then
			self.BeamLength = -300
			self.BeamColor = Color(100,100,255,255)
			self.BeamWidth = 15
			self.BeamPulse = 5
			self.SpriteSize = 60
			self.SpritePulse = 15
			self.SPoint = -25
			self.RenderBounds = 100
			
			self.FDir = self.Entity:GetForward()
		
		elseif self.LaserType == 3 then
			self.BeamLength = 150
			self.BeamColor = Color(255,50,50,255)
			self.BeamWidth = 8
			self.BeamPulse = 2
			self.SpriteSize = 40
			self.SpritePulse = 8
			self.SPoint = 29
			self.RenderBounds = -20
			
			self.FDir = self.Entity:GetUp()
		
		end
		
		//Trace out, see what we hit
		local pos = self.Entity:GetPos()+(self.FDir*self.SPoint)
		local tracedata = {}
		tracedata.start = pos
		tracedata.endpos = pos+(self.FDir*self.BeamLength)
		tracedata.filter = self.Entity
		local trace = util.TraceLine(tracedata)
		
		//Set the rendering bounds
		local startpos = self.Entity:GetPos()+(self.FDir*self.RenderBounds)
		local endpos = trace.HitPos+(self.FDir*self.SPoint)
		if startpos.x > endpos.x and startpos.y > endpos.y and startpos.z > endpos.z then
			self:SetRenderBoundsWS( endpos, startpos )
		else
			self:SetRenderBoundsWS( startpos, endpos )
		end
		
		//Spawn the effect
		//--Beam
		render.SetMaterial( BeamMat )
		render.DrawBeam( pos, trace.HitPos, self.BeamWidth+(self.BeamPulse*math.Rand(-1,1)), 0, 0, self.BeamColor )
		//--Base Sprite (A little more complex, don't want this rendering through the world
		local ViewPos;
		if ValidEntity(LocalPlayer()) then //Seriously, why? I really would like to know.
			ViewPos = LocalPlayer():GetViewModel():GetPos()
		end
		if checkCanSee(ViewPos,pos,{ LocalPlayer(), self.Entity }) then
			render.SetMaterial( FlareMat )
			local Pulse = self.SpritePulse * math.Rand(-1,1)
			render.DrawSprite( pos, (0.7 * self.SpriteSize) + Pulse, (0.7 * self.SpriteSize) + Pulse, self.BeamColor )
		end
		//--Hit Effects (slightly more complex, this wont render if it doesn't hit)
		if trace.Hit then
			//Another Sprite
			if checkCanSee(ViewPos,trace.HitPos, LocalPlayer()) then
				render.SetMaterial( FlareMat )
				local Pulse = self.SpritePulse * math.Rand(-1,1)
				render.DrawSprite( trace.HitPos, self.SpriteSize + Pulse, self.SpriteSize + Pulse, self.BeamColor )
			end
			//Sparkies
			local sparks = EffectData()
			sparks:SetOrigin(trace.HitPos)
			sparks:SetStart(trace.HitPos)
			sparks:SetNormal(trace.HitNormal)
			util.Effect("MetalSpark",sparks)
			//Dust
			local dust = EffectData()
			dust:SetOrigin(trace.HitPos)
			dust:SetStart(trace.HitPos)
			//dust:SetNormal(trace.HitNormal)
			util.Effect("WheelDust",dust)
		end
		
		//local laser = EffectData()
		//laser:SetEntity( self.Entity )
		//laser:SetOrigin( pos )
		//laser:SetStart( trace.HitPos )
		//util.Effect("mining_beam", laser,)
	end
end